/* 
数据类型
ts基本的写法
关键字 变量名：变量的数据类型；
变量名 = 变量值；
或者
关键字 变量名：变量的数据类型 = 变量值；
number 、string 、Boolean、字面量、any 、unknown、void  、联合类型
*/

//number类型
let num: number;
num = 123;
console.log(num);

let num1: number = 123;
console.log(num1);

//string类型
let str1: string = "qqqq";
let str2: string = "1111";
let str3: string = str1 + str2;
console.log(str3);

//布尔类型
let bool: boolean = true;
console.log(bool);

//当使用一个关键字同时声明多个变量时
//当你声明完变量类型时候，你的变量的类型就不能变化，不是该类型就会报错
let str4: string, num4: number, bool1: boolean;
str4 = "3333";
num4 = 123;
bool1 = false
console.log(str4, num4, bool1);

// 当变量和赋值是同时进行的，ts就会自动编译变量的数据类型，可以忽略类型声明，但是实际上它声明了类型
let num5 = 666;
num5 = 777
console.log(num5);

//字面量
let aa: "shun";
aa = "shun";
console.log(aa);

//联合类型
let bb: "zheshu" | "yangyang" | 1111 | false;
bb = 1111;
console.log(bb);

//any 数据类型
// any 和 unknown  都可以赋值为任意数据类型 ，但是any可以赋值给其他数据类型,unknown不能赋值给其他类型，总结 unknown是以中安全的any
// any不建议使用 能使用unknown就不要使用any
let cc: any;
cc = 123;
let dd: string;  // any它可以赋值给任意数据类型
dd == cc;
console.log(cc);
console.log(dd);

//unkonw 数据类型
let abc: unknown;
abc = 123;
abc = false;
let ff: string;
// ff = ee
let gg: unknown;
gg == abc;
console.log(abc);

//void数据类型
// 函数返回值：当函数内部有return 函数的返回值就是return后面的值，当没有return时，函数的返回值undefined
// 形参需要设计数据类型  函数的返回值需要设计数据类型
/* function  函数名（形参1：形参1的数据类型，形参2：形参2的数据类型）:函数返回值的数据类型{
    。。。。
    return xxx
} */
function sum(a: number, b: string): string {
    return a + b;

}
console.log(sum(1, "111"));

//void表示没有任何类型，一般用来表示函数的返回值 undefined或者null
function fun1(a: string, b: number): void {
    let c: string = a + b;
    console.log(c);
    // return console.log(c);
    // return '4536'; 
}
console.log(fun1('aa', 2));

//对象
//当对象的数据类型规定完毕后，创建的对象必须严格按照对象规定的数据类型创建，不能多不能少，数据类型也不能不同
let obj: { name: string, age: number };
obj = {
    name: "lilili",
    age: 18,
}
console.log(obj);

//  ?   在规定类型时，在属性名后面加?，表示该属性可选   可有可无
let obj2: { name: string, age: number, sex?: string }
obj2 = {
    name: "zhang",
    age: 20,
    sex: "女"  //这个可有可无，可写可不写
}
console.log(obj2);

//任意往后面添加属性名，但不知道添加什么属性的时候
let obj3: { name: string, age: number, [propName: string]: unknown }
obj3 = {
    name: "李四",
    age: 20,
    sex: "女",
    hoppy: "玩",
    height: 180
}
console.log(obj3);

//array
// string[]  表示当前数组的元素类型都为字符串
let arr: string[];
arr = ["sss", "aaaa", "vvvv"]
console.log(arr);
// Array<string>  表示当前数组的元素类型都为字符串
let arr0: Array<string>;
arr0 = ['fddd', 'fefaaaa', 'gegggg'];
console.log(arr0);



// number[]表示当前数组的元素类型都为number类型
let arr1: number[];
arr1 = [111, 333, 555]
console.log(arr1);
// Array<number> 表示当前数组元素都为number类型
let arr3: Array<number>;
arr3 = [1, 5, 9];
console.log(arr3);

// 元组 ：元组类型表示的是一个已知元素数量和类型的数组，各个元素的类型不一定相同
let arr4: [string, number, boolean];
arr4 = ["1111", 2222, false]
console.log(arr4);

//枚举enum  对数据类型进行一个补充，赋予数据类型一组友好的名字
enum Hight {
    ping,
    catc,
}
console.log(Hight[0], Hight[1]);

enum Color {
    Yellow,
    Pink,
    Blue,
}
let monkey: Color = Color.Blue
console.log(monkey);

console.log(Color[0], Color[1], Color[2]);

//类型联合   表示取值可以是多种类型
let uu: "zheshu" | "yangyang" | 123 | false;
uu = "zheshu";
uu = 123;
console.log(uu);

function boo(a: string | number, b: number): void {
    console.log(a, b);
}
boo(48, 36)

// 类型断言
// 语法
//方式一： <数据类型>值
//方式二： 值 as 类型

function buu(x:number|string|false){
    if((<string>x).length){
        console.log(111);
        
        return (<string>x).length;
    }else{
        console.log(222);
        
        return x.toString().length
    }
}
console.log(buu(false));

// 类型推断 ts中没有明确指定类型时，自动推断出一个数据类型
// 一种：定义变量并且赋值时，推断为对应的数据类型
// 二种：定义变量没有赋值时，推断它的类型为any 

let app = "plmm";
app = "222"
let appd;
appd = 13;
appd = "111"



































